#pragma once

#include "config.h"
#include "DBManage.h"

#include <jsoncpp/json/json.h>

enum User_Status
{
    ON_LINE = 0,
    OFF_LINE
};

//每一个用户的信息
class UserInfo
{
public:
    UserInfo(){};
    ~UserInfo(){};
public:
    UserInfo(int user_id, std::string& nickname, std::string& telnum,
    std::string& passwd) : user_id_(user_id), nickname_(nickname), 
    telnum_(telnum), passwd_(passwd)
    {}
public:
    //用户基本信息
    int user_id_;
    std::string nickname_;
    std::string telnum_;
    std::string passwd_;

    //用户当前状态 在线or离线
    enum User_Status user_status_;

    //服务端分配给用户的new_socket，方便给好友发送信息
    int tcp_socket_;

    //该用户的好友列表
    std::vector<int> friend_id_;
};



//用户管理类，负责与数据库进行链接，且将数据库内容缓存到内存
class CUserManage
{
    typedef std::pair<int, std::string> pis;
public:
    static CUserManage* GetUserManage();
    ~CUserManage();
public:
    bool Init();
public://for test
    void PrintUser();
    //注册
    int Register(std::string& nickname, std::string& telnum, std::string& passwd);
    //登录验证
    int LoginCheck(std::string telnum, std::string passwd, int socket);
    //返回好友列表
    bool ReturnFriend(int user_id, Json::Value& friend_arr);
    //用户是否在线，在线返回接收方的sock
    int CheckUserStatus(int user_id, int send_id);
    int CheckUserStatus(std::string telnum);
    //获取用户信息
    void GetUser(std::string telnum, UserInfo& ui);
    void GetUser(int uid, UserInfo& ui);
    //插入好友信息
    int RenewFriendInfo(int user_id, int friend_id);
    //退出更新用户状态
    void RenewUserStatus(int user_id);
private:
    CUserManage();
    CUserManage(const CUserManage& user);
    CUserManage& operator=(CUserManage& user);
private:
    CDBManage* db_;

    //缓存用户信息:user_id -> Userinfo
    std::unordered_map<int, UserInfo> user_info_;
    //缓存用户tel对应的uid和passwd，这样登录时可以做到o（1）复杂度
    std::unordered_map<std::string, pis> tel_map_;

    //多线程操作数据库需要同步互斥
    std::mutex db_lock_;

    static CUserManage* user_;

    //预分配的user_id
    int prediction_id;
};


